using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone;
using Microsoft.Phone.Shell;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Controls.Primitives;
using Microsoft.Xna.Framework.Media;

namespace ProtoImaginer.ProtoImage
{
    public partial class ModifyPhoto : PhoneApplicationPage
    {

        //Variables for the application bar buttons
        ApplicationBarIconButton btnCrop;
        ApplicationBarIconButton btnAccept;
        ApplicationBarIconButton btnReject;
        ApplicationBarIconButton btnRotate;

        //Variables for the crop feature
        Point p1, p2;
        bool cropping = false;

        public ModifyPhoto()
        {
            InitializeComponent();

            textStatus.Text = "Select the cropping region with your finger." + " Once completed, tap the crop button to crop the image.";


            //Sets the source to the Image control on the crop page to the WriteableBitmap object created previously.
            DisplayedImageElement.Source = App.CapturedImage;


            //Create event handlers for cropping selection on the picture.
            DisplayedImageElement.MouseLeftButtonDown += new MouseButtonEventHandler(CropImage_MouseLeftButtonDown);
            DisplayedImageElement.MouseLeftButtonUp += new MouseButtonEventHandler(CropImage_MouseLeftButtonUp);
            DisplayedImageElement.MouseMove += new MouseEventHandler(CropImage_MouseMove);


            //Used for rendering the cropping rectangle on the image.
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

            //Creating an application bar and then setting visibility and menu properties.
            ApplicationBar = new ApplicationBar();
            ApplicationBar.IsVisible = true;
            ApplicationBar.IsMenuEnabled = true;

            //This code creates the application bar icon buttons.
            btnCrop = new ApplicationBarIconButton(new Uri("/Icons/appbar.edit.rest.png", UriKind.Relative));
            btnAccept = new ApplicationBarIconButton(new Uri("/Icons/appbar.check.rest.png", UriKind.Relative));
            btnReject = new ApplicationBarIconButton(new Uri("/Icons/appbar.cancel.rest.png", UriKind.Relative));
            btnRotate = new ApplicationBarIconButton(new Uri("/Icons/appbar.questionmark.rest.png", UriKind.Relative));

            //Labels for the application bar buttons.
            btnCrop.Text = "Crop";
            btnAccept.Text = "Accept";
            btnReject.Text = "Reject";
            btnRotate.Text = "Rotate";

            //This code adds buttons to application bar.
            ApplicationBar.Buttons.Add(btnCrop);
            ApplicationBar.Buttons.Add(btnAccept);
            ApplicationBar.Buttons.Add(btnReject);
            ApplicationBar.Buttons.Add(btnRotate);



            //This code will create event handlers for buttons.
            btnCrop.Click += new EventHandler(btnCrop_Click);
            btnAccept.Click += new EventHandler(btnAccept_Click);
            btnReject.Click += new EventHandler(btnReject_Click);
            btnRotate.Click += new EventHandler(btnRotate_Click);

            //Disable buttons so user cannot click until appropriate time.
            btnCrop.IsEnabled = false;
            btnAccept.IsEnabled = false;
            btnReject.IsEnabled = false;

            //Begin storyboard for rectangle color effect.
            Rectangle.Begin();
        }


        void btnRotate_Click(object sender, EventArgs e)
        {
            //Error text for if user does not take a photo before choosing the crop button.
            if (App.CapturedImage == null)
            {
                textStatus.Text = "You must take a picture first.";

            }
            else
            {
                Duration Time_duration = new Duration(TimeSpan.FromSeconds(1));
                Storyboard MyStory = new Storyboard();
                MyStory.Duration = Time_duration;
                DoubleAnimation My_Double = new DoubleAnimation();
                My_Double.Duration = Time_duration;
                MyStory.Children.Add(My_Double);
                RotateTransform MyTransform = new RotateTransform();
                MyTransform.CenterX = 150;
                MyTransform.CenterY = 150;
                Storyboard.SetTarget(My_Double, MyTransform);
                Storyboard.SetTargetProperty(My_Double, new PropertyPath("Angle"));
                My_Double.To = 90;
                DisplayedImageElement.RenderTransform = MyTransform;
                MyStory.Begin();
            }
        
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            if (cropping)
            {
                rect.SetValue(Canvas.LeftProperty, (p1.X < p2.X) ? p1.X : p2.X);
                rect.SetValue(Canvas.TopProperty, (p1.Y < p2.Y) ? p1.Y : p2.Y);
                rect.Width = (int)Math.Abs(p2.X - p1.X);
                rect.Height = (int)Math.Abs(p2.Y - p1.Y);
            }
        }

        void CropImage_MouseMove(object sender, MouseEventArgs e)
        {
            p2 = e.GetPosition(DisplayedImageElement);
        }

        void CropImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            p2 = e.GetPosition(DisplayedImageElement);
            cropping = false;
        }

        void CropImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            btnCrop.IsEnabled = true;
            p1 = e.GetPosition(DisplayedImageElement);
            p2 = p1;
            rect.Visibility = Visibility.Visible;
            cropping = true;
        }

        void btnReject_Click(object sender, EventArgs e)
        {
            //Sets the cropped image back to the original image. For users that want to revert changes.
            DisplayedImageElement.Source = App.CapturedImage;

            //Buttons are disabled and user cannot proceed to use the below until they crop an image again.
            btnCrop.IsEnabled = false;
            btnAccept.IsEnabled = false;
            btnReject.IsEnabled = false;

            //Instructional Text
            textStatus.Text = "Select the cropping region with your finger." + " Once completed, tap the crop button to crop the image.";

        }

        void btnAccept_Click(object sender, EventArgs e)
        {
            //Make progress bar visible for the event handler as there may be posible latency.
            progressBar2.Visibility = Visibility.Visible;

            //Create filename for JPEG in isolated storage
            String tempJPEG = "TempJPEG.jpg";

            //Create virtual store and file stream. Check for duplicate tempJPEG files.
            var myStore = IsolatedStorageFile.GetUserStoreForApplication();
            if (myStore.FileExists(tempJPEG))
            {
                myStore.DeleteFile(tempJPEG);
            }
            IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);

            //Encode the WriteableBitmap into JPEG stream and place into isolated storage.
            Extensions.SaveJpeg(App.CroppedImage, myFileStream, App.CroppedImage.PixelWidth, App.CroppedImage.PixelHeight, 0, 85);
            myFileStream.Close();

            //Create a new file stream.
            myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read);

            //Add the JPEG file to the photos library on the device.
            MediaLibrary library = new MediaLibrary();
            Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream);
            myFileStream.Close();

            progressBar2.Visibility = Visibility.Collapsed;

            textStatus.Text = "Picture saved to photos library on the device.";
        }

        void btnCrop_Click(object sender, EventArgs e)
        {
            // Get the size of the source image captured by the camera
            double originalImageWidth = App.CapturedImage.PixelWidth;
            double originalImageHeight = App.CapturedImage.PixelHeight;


            // Get the size of the image when it is displayed on the phone
            double displayedWidth = DisplayedImageElement.ActualWidth;
            double displayedHeight = DisplayedImageElement.ActualHeight;

            // Calculate the ratio of the original image to the displayed image
            double widthRatio = originalImageWidth / displayedWidth;
            double heightRatio = originalImageHeight / displayedHeight;

            // Create a new WriteableBitmap. The size of the bitmap is the size of the cropping rectangle
            // drawn by the user, multiplied by the image size ratio.
            App.CroppedImage = new WriteableBitmap((int)(widthRatio * Math.Abs(p2.X - p1.X)), (int)(heightRatio * Math.Abs(p2.Y - p1.Y)));


            // Calculate the offset of the cropped image. This is the distance, in pixels, to the top left corner
            // of the cropping rectangle, multiplied by the image size ratio.
            int xoffset = (int)(((p1.X < p2.X) ? p1.X : p2.X) * widthRatio);
            int yoffset = (int)(((p1.Y < p2.Y) ? p1.Y : p2.X) * heightRatio);

            // Copy the pixels from the targeted region of the source image into the target image, 
            // using the calculated offset
            for (int i = 0; i < App.CroppedImage.Pixels.Length; i++)
            {
                int x = (int)((i % App.CroppedImage.PixelWidth) + xoffset);
                int y = (int)((i / App.CroppedImage.PixelWidth) + yoffset);
                App.CroppedImage.Pixels[i] = App.CapturedImage.Pixels[y * App.CapturedImage.PixelWidth + x];
            }

            // Set the source of the image control to the new cropped bitmap
            DisplayedImageElement.Source = App.CroppedImage;
            rect.Visibility = Visibility.Collapsed;


            //Enable  accept and reject buttons to save or discard current cropped image.
            //Disable crop button until a new cropping region is selected.
            btnAccept.IsEnabled = true;
            btnReject.IsEnabled = true;
            btnCrop.IsEnabled = false;

            //Instructional text
            textStatus.Text = "Continue to crop image, accept, or reject.";
        }
    }
}
